package com.ymatou.iapi.trading.userquery.testcase;

import java.math.BigDecimal;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.CollectionUtils;

import com.ymatou.iapi.optrade.parameter.enums.CancelOrderTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.req.AgreeRefundReq;
import com.ymatou.iapi.optrade.parameter.req.ApplyRefundReq;
import com.ymatou.iapi.optrade.parameter.vo.SalesRefundInfoVo;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.service.AgreeRefundCall;
import com.ymatou.iapi.optrade.service.BargainGroupService;
import com.ymatou.iapi.optrade.service.RefundService;
import com.ymatou.iapi.synctrade.parameter.mongo.Order;
import com.ymatou.iapi.synctrade.service.TradingSyncService;
import com.ymatou.iapi.trading.userquery.parameter.GetBuyerGroupOrderInfosBean;
import com.ymatou.iapi.trading.userquery.parameter.resp.GetBuyerGroupOrderInfosResp;
import com.ymatou.iapi.trading.userquery.service.GetBuyerGroupOrderInfosCall;
import com.ymt.core.tool.FormatUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.AccountCallServiceV2;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceHunterOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.common.order.userquery.OrderInfoBuilder;
import com.ymttest.common.order.userquery.model.vo.BargainGroupInfo;
import com.ymttest.common.order.userquery.model.vo.OrderInfo;
import com.ymttest.common.order.userquery.util.OrderHelper;
import com.ymttest.database.mongo.OrderQueryWapper;
import com.ymttest.database.mongo.UserIndexQueryWapper;
import com.ymttest.database.mongo.config.UserIndexField;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.TestDataManager;

/**
 *  根据主单号获取订单详情
 */
@TestSuite
public class Ts_GetBuyerGroupOrderInfos {

	private static GetBuyerGroupOrderInfosBean req;
	private static GetBuyerGroupOrderInfosCall getBuyerGroupOrderInfosCall;
	
	private static Integer userId = 20238699;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("根据主单号获取订单详情");
	}

	@Before
	public void caseUp() {
		req = new GetBuyerGroupOrderInfosBean();
		getBuyerGroupOrderInfosCall = new GetBuyerGroupOrderInfosCall();
		
		String accountid1;
		try {
			accountid1 = AccountCallServiceV2.getAccountId(userId);
			AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
					9000000), new BigDecimal(0));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(getBuyerGroupOrderInfosCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	private void constructExpectedResult(GetBuyerGroupOrderInfosResp resp) {
		
		Query query = Query.query(Criteria.where(UserIndexField.USER_ID).is(req.getUserId())
                .and(UserIndexField.MAIN_ORDER_ID).is(req.getOrderGroupId())
                .and(UserIndexField.ORDER_TYPE).nin(OrderHelper.getMemberOrderTypes())
                .norOperator(Criteria.where(UserIndexField.HUNTER_ID).gt(0)));

		List<Long> orderIdList = new UserIndexQueryWapper().queryOrderId(query,
				req.getUserId());
		List<Order> orderList = new OrderQueryWapper().findByIds(orderIdList);
		if (!CollectionUtils.isEmpty(orderList)) {
			orderList.forEach(o -> {
				resp.getOrderInfos().add(
						OrderInfoBuilder.convertFromOrder(o, false));
			});
		}
	}

	private void verify() {

		GetBuyerGroupOrderInfosResp expectResponse = new GetBuyerGroupOrderInfosResp();
		constructExpectedResult(expectResponse);

		GetBuyerGroupOrderInfosResp actualResponse = getBuyerGroupOrderInfosCall
				.getBuyerGroupOrderInfosResp();

		List<OrderInfo> expectOrders = expectResponse.getOrderInfos();
		List<OrderInfo> actualOrders = actualResponse.getOrderInfos();

		for (int i = 0; i < expectOrders.size(); i++) {

			OrderInfo expect = expectOrders.get(i);
			OrderInfo actual = actualOrders.get(i);

			expect.verify(actual);

			if (actual != null) {
				BargainGroupInfo act = actual.getBargainGroup();
				BargainGroupInfo exp = new Ts_GetBuyerOrderInfosV2()
						.getBargainGroupInfoFromMssql(expect.getOrderId());
				if (exp == null) {

					DataUtil.verify(
							null,
							act,
							String.format(
									"验证 sqlserver中订单id:%d 没有参加砍价团(orderInfos.bargainGroup == null)",
									expect.getOrderId()));
				} else {
					DataUtil.verifyObject(exp, act,
							"砍价团信息orderInfos.bargainGroup");
				}
			}
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_001() {
		Logger.start(true, "订单状态为1 下单,根据主单号获取订单详情");
		try {
			
			TradingServiceResp placeOrder = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);
			
			long tradingId = placeOrder.getTradingId();
			long userId = placeOrder.getUserId();

			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_002() {
		Logger.start(true, "订单状态为2 付款,根据主单号获取订单详情");
		try {
			TradingServiceResp placeOrder = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long userId = placeOrder.getUserId();

			long tradingId = placeOrder.getTradingId();

			long orderId = placeOrder.getOrderList().get(0).getOrderId();

			// 支付订单
			TradingCallService.payOrder(userId, placeOrder.getPayableAmount(),
					tradingId);

			TradingSyncService.getSyncResult(orderId);
			
			Logger.comment("前置数据准备结束");

			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);
			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_003() {
		Logger.start(true, "订单状态为3 取消订单,根据主单号获取订单详情");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrder = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);
			long userId = placeOrder.getUserId();
			long tradingId = placeOrder.getTradingId();
			long orderId = placeOrder.getOrderList().get(0).getOrderId();
			
			// 取消订单
			TradingCallService.cancelOrder(orderId,
					CancelOrderTypeEnum.BUYER_CANCEL_ORDER, userId);

			TradingSyncService.getSyncResult(orderId);
			
			Logger.comment("前置数据准备结束");
			
			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_004() {
		Logger.start(true, "订单状态为 接单,根据主单号获取订单详情");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrder = TradingCallService.orderAccept();
			long userId = placeOrder.getUserId();
			long tradingId = placeOrder.getTradingId();

			long orderId = placeOrder.getOrderList().get(0).getOrderId();
			
			TradingSyncService.getSyncResult(orderId);
			Logger.comment("前置数据准备结束");

			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_005() {
		Logger.start(true, "订单状态为 发货,根据主单号获取订单详情");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getTradingId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();

			TradingCallService.payOrder(userId, useAccountAmount, tradingId);

			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);

			TradingSyncService.getSyncResult(orderId);

			Logger.comment("前置数据准备结束");

			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_006() {
		Logger.start(true, "订单状态为 确认收货根据主单号获取订单详情");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			// 创建一个拼邮的订单
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			
			// 支付订单
			TradingCallService.payOrder(userId,
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			// 接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			TradingSyncService.getSyncResult(orderId);
			
			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);
			
			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			
			TradingCallService.confirmReceive(userId, orderId);

			TradingSyncService.getSyncResult(orderId);

			Logger.comment("前置数据准备结束");

			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_007() {
		Logger.start(true, "订单状态为 申请退款根据主单号获取订单详情");
		try {
			
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);

			com.ymatou.iapi.optrade.resp.Order order = placeOrderResp.getOrderList().get(0);

			long userId = placeOrderResp.getUserId();
			Long orderId = order.getOrderId();
			long tradingId = placeOrderResp.getTradingId();
			long sellerId = order.getSellerId();

			// 支付
			TradingCallService.payOrder(placeOrderResp.getUserId(),
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			// 接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			TradingSyncService.getSyncResult(orderId);
			
			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);

			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			TradingSyncService.getSyncResult(orderId);
			
			TradingCallService.confirmReceive(userId, orderId);
			TradingSyncService.getSyncResult(orderId);
			
			RefundService.applyRefund(order);

			Thread.sleep(5000);
			
			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_008() {
		Logger.start(true, "订单状态为 退款成功 根据主单号获取订单详情");
		try {
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);

			com.ymatou.iapi.optrade.resp.Order order = placeOrderResp.getOrderList().get(0);

			long userId = placeOrderResp.getUserId();
			Long orderId = order.getOrderId();
			long tradingId = placeOrderResp.getTradingId();
			long sellerId = order.getSellerId();

			// 支付
			TradingCallService.payOrder(placeOrderResp.getUserId(),
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			// 接单
			TradingCallService.sellerAcceptOrder(order.getSellerId(), orderId);
			TradingSyncService.getSyncResult(orderId);
			
			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);

			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			TradingSyncService.getSyncResult(orderId);
			
			TradingCallService.confirmReceive(userId, orderId);
			TradingSyncService.getSyncResult(orderId);
			
			ApplyRefundReq applyRefundReq = RefundService.applyRefund(order);

			Thread.sleep(5000);
			
			AgreeRefundReq salesrefundsuccessReq = new AgreeRefundReq();
			AgreeRefundCall salesrefundsuccessCall = new AgreeRefundCall();
			
			salesrefundsuccessReq.setOrderId(orderId);
			
			int i = 0;
			for (SalesRefundInfoVo salesRefundInfoVo : applyRefundReq
					.getSalesRefundInfoList()) {

				salesrefundsuccessReq.setRefundBillNo(salesRefundInfoVo
						.getRefundBillNo());
				salesrefundsuccessCall.setData(salesrefundsuccessReq);

				Logger.comment(String.format("orderid: %s 第 %s 个商品 退款执行",
						orderId, i + 1));

				salesrefundsuccessCall.callService();

				Logger.verifyEquals("true",
						salesrefundsuccessCall.getString("success"),
						"验证退货退款成功返回");
				i++;
			}
			
			Thread.sleep(5000);
			
			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_009() {
		Logger.start(true, "验证砍价团信息，查询成功, 团长开团 组团失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			// 砍价团id
			String bizId = TestDataManager.getRandomNum(9);

			TradingServiceResp placeOrderResp = BargainGroupService
					.openGroup(bizId);

			// 参团
			TradingServiceResp placeOrder2 = BargainGroupService
					.joinGroup(bizId);

			long orderId = placeOrder2.getOrderList().get(0).getOrderId();

			Logger.comment("前置数据准备结束");

			BargainGroupService.notifyOrderBizStatus(bizId, orderId, 2, -3);

			TradingSyncService.getSyncResult(orderId);

			req.setUserId((int)placeOrderResp.getUserId());
			req.setOrderGroupId(placeOrderResp.getTradingId());

			String s = FormatUtil.beanToHttpString(req, true, true);

			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_GetBuyerGroupOrderInfos_010() {
		Logger.start(true, "订单状态为1，推手订单,根据主单号获取订单详情");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			long hunterId = 4321;
			
			TradingServiceResp placeOrder = TradingPlaceHunterOrderCallService
					.placeHunterOrder(hunterId, 2);
			long userId = placeOrder.getUserId();
			long tradingId = placeOrder.getTradingId();

			long orderId = placeOrder.getOrderList().get(0).getOrderId();
			Logger.comment("前置数据准备结束");

			TradingSyncService.getSyncResult(orderId);

			req.setUserId((int)userId);
			req.setOrderGroupId(tradingId);

			String s = FormatUtil.beanToHttpString(req, true, true);
			getBuyerGroupOrderInfosCall.setData(s);
			getBuyerGroupOrderInfosCall.callService();

			Logger.verifyEquals(0, getBuyerGroupOrderInfosCall.getData()
					.getJSONArray("orderInfos").length(), "app买家查询无法查找hunter订单");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
